package com.bitbits.plugins.completions;

import com.bitbits.plugins.settings.Px2rpxSettings;
import com.bitbits.plugins.utils.NumberUtils;
import com.bitbits.plugins.utils.StringUtils;
import com.intellij.codeInsight.completion.*;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupElementBuilder;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.editor.CaretModel;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.util.TextRange;
import com.intellij.util.ProcessingContext;
import org.jetbrains.annotations.NotNull;

public class Px2rpxProvider extends CompletionProvider<CompletionParameters> {

    private final Px2rpxSettings settings;

    public Px2rpxProvider() {
        this.settings = Px2rpxSettings.getInstance();
    }

    @Override
    protected void addCompletions(
            @NotNull CompletionParameters parameters,
            @NotNull ProcessingContext context,
            @NotNull CompletionResultSet resultSet) {
        String pxText = parameters.getPosition().getParent().getFirstChild().getText();
        float rpxValue = NumberUtils.toScale((Float.parseFloat(pxText)) / this.settings.getRatio(), 2);
        resultSet.addElement(LookupElementBuilder
                .create(pxText + "px -> " + rpxValue + "rpx")
                .withInsertHandler((ctx, item) -> replace(ctx, item, rpxValue)));
    }

    /**
     * IDEA在解析代码的时候会建立一个二维坐标系，生成单元格并将代码按照字符顺序一个一个填充进坐标系中
     * 通过offset可以快速获取某个对象相对坐标系左上方的字符数量偏移（以左上方为0）
     * 详见：https://plugins.jetbrains.com/docs/intellij/coordinates-system.html#caret-logical-position
     */
    private static void replace(@NotNull InsertionContext ctx, @NotNull LookupElement item, float rpxValue) {
        // 获取当前文档对像
        Document doc = ctx.getDocument();
        // 获取当前指针对象
        CaretModel caretModel = ctx.getEditor().getCaretModel();
        // 通过指针对象偏移值获取当前光标位置代码行号信息
        int currentLineNum = doc.getLineNumber(caretModel.getOffset());
        // 通过当前行号获取当前行行首相对整个代码文档的便宜值
        int currentLineStartOffset = doc.getLineStartOffset(currentLineNum);
        // 获取当前行内容
        String lineContent = doc.getText(new TextRange(currentLineStartOffset, caretModel.getOffset()));

        // 新开一个线程进行替换字符串操作
        WriteCommandAction.runWriteCommandAction(ctx.getProject(), () -> {
            doc.replaceString(currentLineStartOffset + StringUtils.firstNumIndexOf(lineContent), caretModel.getOffset(), rpxValue + "rpx;");
        });
    };
}
